The present invention relates to computer systems and more particularly to a diagnostic technique for debugging memory corruption.
During execution of a program, objects are allocated memory, which is used to store information. An object is an entity that encapsulates data and, in some languages, operations associated with the object. Since the encapsulated data is stored in memory, objects are associated with particular regions of memory that are allocated and deallocated by the program. In most environments, memory management routines are provided to allow programmers to dynamically allocate and deallocate memory for objects. In some run-time environments, such as in a JAVA(trademark) virtual machine, the memory management routines also provide for garbage collection, which automatically reclaims memory for objects that are no longer used.
Due to programming errors, the memory of an object or other data structure may be unintentionally modified. This type of error is referred to as xe2x80x9cmemory corruption,xe2x80x9d and there are many causes for memory corruption, such as overwriting beyond the bounds of an object (into another object), writing to an uninitialized pointer, writing to a pointer that used to point to an object but that had been deallocated, and other misuses of pointers.
Memory corruption is a notoriously difficult and subtle problem to fix. Typically, the effect of the corruption does not manifest until well after the corruption occurred. For example, an object may be allocated in a run-time environment employing garbage collection. This object may contain a reference to another object, typically stored as a machine pointer. If the machine pointer in the object is corrupted due to a programming error, then using the corrupted pointer may result in attempting to access an invalid area of memory, producing a segmentation fault or other operating system fault and generating a core dump. In many cases, the corrupted pointer lies dormant until much later, when the garbage collector inspects pointers contained in the object.
Conventional techniques for identifying the cause of a memory corruption are laborious and cumbersome. Although it is generally possible to ascertain the memory location of the corrupted part of the object by inspecting the core dump, it is difficult to identify which operation actually corrupted the object. Because most memory corruption occurs from misusing pointers, the operation that corrupted the object often bears no apparent relationship to the object.
To debug a memory corruption, a programmer typically establishes the operating conditions, such as the input data, that cause the memory corruption to be consistently reproducible. Inspecting the core dump, the programmer then figures out the memory address of the part of the object that was overwritten and looks for changes to that memory location. Many debuggers provide xe2x80x9cwatchpoints,xe2x80x9d which direct the debugger to break execution of a program when a specified memory location changes. Accordingly, the programmer would set a watchpoint on the memory location that was corrupted and inspect every change to that memory location.
Unfortunately, that memory location may be legitimately used for thousands of times from the beginning of the program before becoming corrupted. In fact, that memory location may be used by many different objects before the corrupted object was even allocated, because memory is often reused. As a result, the programmer may be forced to inspect thousands of benign modifications to a particular memory address. Even if the memory address changes relatively few times, using watchpoints is a slow and cumbersome procedure. For example, with software watchpoints, execution of the program is slowed by many orders of magnitude, because the debugger has to step through the program, operation by operation, and check if the specified memory location has changed. Even with hardware watchpoints, the debugging operation by the user is slow, because the user has to check for each modification if the modification is not benign.
Therefore, there is a need for a diagnostic technique that can quickly help the programmer to identify the cause of memory corruption errors.
This need and others are addressed by the present invention, in which the memory management routines are instrumented (e.g. in a debugging compilation mode) to check if the address of the object they are handling is equal to the value of a predetermined pointer. If the address of the object equals the value of the pointer, then a debugging routine is called. One advantage to calling the debugging routine is that the programmer can set a xe2x80x9cbreakpointxe2x80x9d on the debugging routine. A breakpoint is facility provided by debuggers that breaks execution of a program when a specified instruction is executed, for example, the first instruction of a function, to allow the programmer inspect the state of the program at that point. Setting a breakpoint and breaking execution of the program when the breakpoint is encountered usually does not affect the speed of the rest of the program in the debugger.
To use these instrumented memory management routines, a programmer ascertains the address of the object that was corrupted, typically by inspecting the core dump, and sets the global pointer to that address. In addition, the programmer sets a breakpoint on the debugging routine and starts execution of the program. All of these operations can be performed in the debugger without having to recompile the program. When the instrumented memory management routines handle an object whose address equals the value of the global pointer, the debugging routine is called, which trips the breakpoint. For example, this event may occur whenever an object is allocated at, deallocated from, or relocated from or to that address. At the last breakpoint before the object is corrupted, the programmer then sets a watchpoint on the corrupted memory address within the object and waits for the corruption to occur. Since a breakpoint rather than a watchpoint is used to pass over working areas of the program (because breakpoints are typically triggered much less often than watchpoints on changes to a watched memory location), execution of the program in the debugger is fast, and much less time is spent in finding the source of memory corruptions.
Accordingly one aspect of the invention relates to a method and software for debugging a memory corruption in a program. An instrumented version of the program is executed with a memory management routine that compares an address of an object handled by the memory management routine and a value of a pointer, and, if the address of the object equals the value of the pointer, calls a debugging function. The methodology also includes setting the pointer to a desired value and setting a breakpoint on the debugging function.
In one embodiment, execution of the instrumented version of the program is broken when the breakpointed debugging function is called, so that a watchpoint may be set on a memory location afflicted with the memory corruption; and execution is continued until the memory location changes.
Another aspect of the invention pertains to a method and software for debugging a memory corruption in a program by: comparing an address of an object handled by a memory management routine of the program and a value of a predetermined pointer; and, if the address of the object equals the value of the predetermined pointer, then calling a debugging function. In one embodiment, the memory management routine may be a memory allocation or a memory deallocation routine.
Yet another aspect of the invention involves a method and software for debugging a memory corruption in a program by instrumenting or conditionally compiling one or more memory management routines of the program to perform the steps of: comparing an address of an object handled by a memory management routine of the program and a value of a pointer; and if the address of the object equals the value of the pointer, then calling a debugging function.
Still other objects and advantages of the present invention will become readily apparent from the following detailed description, simply by way of illustration of the best mode contemplated of carrying out the invention. As will be realized, the invention is capable of other and different embodiments, and its several details are capable of modifications in various obvious respects, all without departing from the invention. Accordingly, the drawing and description are to be regarded as illustrative in nature, and not as restrictive.